<?php

namespace Core\Application;

use Core\Http\Request as HttpRequest;
use Core\Http\Response as HttpResponse;
use Swoole\Http\Server;
use Swoole\Http\Request;
use Swoole\Http\Response;

class RunSwoole  extends Run
{
    /**
     * swoole run
     */
    public function run()
    {
        // 显示启动信息
        $this->echoStartInfo();

        // run server
        $http = new Server('0.0.0.0', 9501);
        $http->on('Request', function (Request $request, Response $response) {
            try {
                // 设置请求数据
                $this->initializeRequest($request);

                // 调度处理
                $this->dispatch(
                    $request->server['request_method'],
                    $request->server['request_uri']
                );
            } catch (\Exception $e) {
                HttpResponse::getInstance()->fail($e->getMessage(), 600100);
            }

            // 输出数据到客户端
            $this->responseSend($response);
        });

        $http->start();
    }

    /**
     * 初始化Request
     * GET|POST会同时接收到数据, 处理后会被覆盖
     */
    public function initializeRequest($request)
    {
        // The GET parameters
        $get = $request->get ?: [];

        // The POST parameters
        $post = $request->post ?: [];

        // The request attributes (parameters parsed from the PATH_INFO, ...)
        $attributes = [];

        // The COOKIE parameters
        $cookies = $request->cookie ?: [];

        // The FILES parameters
        $files = $request->files ?: [];

        // The SERVER parameters
        $server = [];
        foreach ($request->server ?: [] as $key => $value) {
            $server[strtoupper($key)] = $value;
        }

        // X-Request-Id
        if (!array_key_exists('HTTP_X-Request-Id', $server)) {
            $server['HTTP_X-Request-Id'] = substr(md5(uniqid()), 0, 6);
        }

        // The raw body data
        $content = $request->getContent();

        HttpRequest::getInstance()->initialize(
            $get,
            $post,
            $attributes,
            $cookies,
            $files,
            $server,
            $content
        );
    }

    /**
     * 输出返回数据到客户端
     */
    public function responseSend($response)
    {
        $httpResponse = HttpResponse::getInstance();

        $response->header('Server', 'nova-api-server');
        foreach ($httpResponse->headers->allPreserveCaseWithoutCookies() as $name => $values) {
            foreach ($values as $value) {
                $response->header($name, $value);
            }
        }

        $response->end($httpResponse->getContent());
    }

    /**
     * 显示启动信息
     */
    public function echoStartInfo()
    {
        // 启动信息
        echo "Nova API"                                         . PHP_EOL;
        echo "Port   : 9501"                                    . PHP_EOL;
        echo "Start  : " . date('Y-m-d H:i:s')                  . PHP_EOL;
    }
}
